<?php

Solar::loadClass('Domain51_Service_Amazon_Util_Header');

class Domain51_Service_Amazon_Util_Connection extends Solar_Base 
{
    protected $_Domain51_Service_Amazon_Util_Connection = array(
        'connection_type' => 'zend',
        'url' => 'https://s3.amazonaws.com'
    );
    
    private $_validConnectionTypes = array('pecl', 'zend', 'pear');
    private $_header = null;
    
    public function __construct($config = null)
    {
        parent::__construct($config);
        
        if (!in_array(
            $this->_config['connection_type'], 
            $this->_validConnectionTypes)
        ) {
            throw $this->_exception(
                'ERR_UNKNOWN_CONNECTION_TYPE',
                array('connection_type' => $this->_config['connection_type'])
            );
        }
        assert('$config["header"] instanceof Domain51_Service_Amazon_Util_Header');
        $this->_header = $config['header'];
    }
    
    public function getHeader() 
    {
        return $this->_header;
    }
    
    public function setHeader($header)
    {
        $this->_header = $header;
    }
    
    public function doRequest($type, $uri, $body = '')
    {
        // setup Amazon headers
        $this->_header->setType($type);
        $this->_header->setUrl($uri);
        $this->_header->add('Host', substr($this->_config['url'], strpos($this->_config['url'], '//') + 2));
        $this->_header->add('Date', gmdate(DATE_RFC822));
        
        // send to appropriate adapter
        $adapterMethod = '_' . $this->_config['connection_type'] . '_doRequest';
        $response = $this->$adapterMethod($type, $uri, $body);
        $responseConfig = array(
            'connection_type' => $this->_config['connection_type'],
            'response' => $response
        );
        return Solar::factory(
            'Domain51_Service_Amazon_Util_Connection_Response',
            $responseConfig
        );
    }
    
    private function _pecl_doRequest($type, $uri, $body = '') 
    {
        $request = new HttpRequest();
        $request->setUrl($this->_config['url'] . $uri);
        switch ($type) {
        case 'GET':
            $request->setMethod(HttpRequest::METH_GET);
            break;
        
        case 'DELETE' :
            $request->setMethod(HttpRequest::METH_DELETE);
            break;
        
        case 'HEAD' :
            $request->setMethod(HttpRequest::METH_HEAD);
            break;
        
        case 'PUT':
            $request->setMethod(HttpRequest::METH_PUT);
            if (!empty($body)) {
                $request->setPutData($body);
            }
            break;
        }
        
        $request->setHeaders($this->_header->toArray());
        $response = $request->send();
        return $response;
    }
    
    
    private function _zend_doRequest($type, $uri, $body = '') 
    {
        require_once 'Zend/Http/Client.php';
        
        $request = new Zend_Http_Client();
        $request->setUri($this->_config['url'] . $uri);
        
        $zendHeaders = array();
        foreach ($this->_header->toArray() as $key => $value) {
            $zendHeaders[$key] = "$key: $value";
        }
        
        $request->setHeaders($zendHeaders);
        
        switch ($type) {
            case 'GET' :
                return $request->get();
                break;
            case 'PUT' :
                return $request->put($body);
                break;
            case 'DELETE':
                return $request->delete();
                break;
            case 'HEAD':
                throw $this->_exception(
                    'ERR_METHOD_NOT_IMPLEMENTED',
                    array(
                        'method' => 'HEAD',
                        'message' => 'Unable to make HEAD call as of Zend_Http_Client 0.2.0'
                    )
                );
                break;
        }
        return $request->send();
    }
    
    private function _pear_doRequest($type, $uri) 
    {
        require 'HTTP/Request.php';
        $request = new HTTP_Request();
        $request->setUrl($this->_config['url'] . $uri);
        
        $request->_requestHeaders = array();
        foreach ($this->_header->toArray() as $key => $value) {
            $request->addHeader($key, $value);
        }
        
        $request->sendRequest();
        return $request;
    }
}